package org.jdpf.gui.rcp.neteditor.core.elements;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.swt.graphics.Point;
import org.jdpf.gui.rcp.neteditor.core.blocks.GInspector;
import org.jdpf.gui.rcp.neteditor.core.blocks.IGraphicBlock;
import org.jdpf.gui.rcp.neteditor.core.util.Utility;

public class GraphicNet implements IValidable {
	private List<IGraphicBlock> blocks;

	private List<GraphicWire> wires;

	private String netFileName;

	private String netName;

	private String paramFileName;

	private GraphicNetAsTaskValidationStatus status;

	private String gnetId;

	private boolean validationEnabled;

	public GraphicNet(String netId, String netName, String netFile, String paramFile) {
		this.gnetId = netId;
		this.netName = netName;
		this.netFileName = netFile;
		this.paramFileName = paramFile;
		this.validationEnabled = true;
		blocks = new ArrayList<IGraphicBlock>();
		wires = new ArrayList<GraphicWire>();
	
		updateValidationStatus();
	}
	

	/*
	public GraphicNet() {
		this.gnetId = "null";
		this.netName = "null";
		this.netFileName = "null";
		this.paramFileName = "null";
		blocks = new ArrayList<IGraphicBlock>();
		wires = new ArrayList<GraphicWire>();
	}
	*/

	public void addBlock(IGraphicBlock block) {
		if (block.getTransitionId() == null)
			block.setTransitionId(Utility.getDefault().getUniqueTransitionId(
					this));

		blocks.add(block);

		updateValidationStatus();
	}

	public void removeBlock(IGraphicBlock block) {
		blocks.remove(block);
		
		for (GraphicWire wire : block.getInputWireList()) {
			if (wire != null){
				wire.getSource().addOutputWire(null, wire.getSourceOrder());
				wire.getTarget().addInputWire(null, wire.getTargetOrder());
				wires.remove(wire);
			}
		}
		for (GraphicWire wire : block.getOutputWireList()) {
			if (wire != null){
				wire.getSource().addOutputWire(null, wire.getSourceOrder());
				wire.getTarget().addInputWire(null, wire.getTargetOrder());
				wires.remove(wire);	
			}
		}

		updateValidationStatus();
	}

	public void updateValidationStatus() {
		if(validationEnabled)
			status = Utility.getDefault().validateGraphicNetAsTask(this);
		else
			status = new GraphicNetAsTaskValidationStatus("Validation disabled", GraphicNetAsTaskValidationStatus.WARNING);
	}

	public void addWire(GraphicWire wire) {
		wires.add(wire);

		updateValidationStatus();
	}

	public void removeWire(GraphicWire wire) {
		wire.getSource().addOutputWire(null, wire.getSourceOrder());
		wire.getTarget().addInputWire(null, wire.getTargetOrder());
		wires.remove(wire);

		updateValidationStatus();
	}

	public List<GraphicWire> getGraphicWireList() {
		return wires;
	}

	public List<IGraphicBlock> getBlockList() {
		return blocks;
	}

	public List<GInspector> getInspectorList() {
		List<GInspector> list = new ArrayList<GInspector>();

		for (IGraphicBlock block : getBlockList()) {
			if (block.isInspectioned())
				list.add(block.getInspector());
		}

		return list;
	}

	public GraphicNetAsTaskValidationStatus getValidationStatus() {
		return status;
	}

	public void setNetFileName(String file) {
		this.netFileName = file;
	}

	public void setParamFileName(String file) {
		this.paramFileName = file;
	}

	public String getParamFileName() {
		return paramFileName;
	}

	public String getNetFileName() {
		return netFileName;
	}

	public void setNetName(String name) {
		this.netName = name;
	}

	public String getNetName() {
		return netName;
	}


	public String getGraphicNetId() {
		return gnetId;
	}

	public void setGraphicNetId(String id){
		this.gnetId = id;
	}


	public IGraphicBlock getBlock(String transitionId) {
		IGraphicBlock block = null;
		boolean flag = true;
		Iterator<IGraphicBlock> it = blocks.iterator();
		while(it.hasNext() && flag){
			block = it.next();
			if(block.getTransitionId().equals(transitionId)){
				flag = false;
			} //Check if the block searched is an Inspector Block 
			else if(block.isInspectioned() && block.getInspector().isInspectorBlockSet()){
				block = block.getInspector().getInspectorBlock();
				if(block.getTransitionId().equals(transitionId)){
					flag=false;
				}
			}
		}
		return block;
	}

	public void enableValidation(boolean enable) {
		this.validationEnabled = enable;
	}
	
	public void moveAllBlocks(Point offset){
		for(IGraphicBlock block : getBlockList()){
			block.getPosition().x += offset.x;
			block.getPosition().y += offset.y;
		}
		
		for(GInspector insp : getInspectorList()){
			insp.getPosition().x += offset.x;
			insp.getPosition().y += offset.y;
		}
	}
}
